﻿// <copyright file="TestFactoryHelper.cs" company="Sinbadsoft">
//        Copyright (c) Sinbadsoft 2009.
//        This file is released under the terms of the
//        GNU Library General Public License (LGPL) version 2.1
//        Please refer to the "License.txt" accompanying this file.
// </copyright>
// <author>Chaker NAKHLI</author>
// <email>Chaker.Nakhli@Sinbadsoft.com</email>
// <date>2009/04/17</date>

namespace Sinbadsoft.AdvancedCollections.Tests.ReversibleDictionary
{
    using System;
    using System.Collections.Generic;
    using MbUnit.Framework;

    /// <summary>
    /// Helper class for <see cref="IReversibleDictionary{TKey,TValue}"/> test generation.
    /// </summary>
    /// <remarks>
    /// This class generates data sets with types (<see cref="Int32"/>, <see cref="Int32"/>) and 
    /// (<see cref="String"/>, <see cref="String"/>). The built test cases use the
    /// fundamental <see cref="IReversibleDictionary{TKey,TValue}"/> tests implmeneted in <see cref="CommonTests"/>.
    /// </remarks>
    /// <seealso cref="CommonTests"/>
    internal class TestFactoryHelper
    {
        private readonly Factory_Delegate<int, int> factoryForIntToInt;
        private readonly Factory_Delegate<string, string> factoryForStringToDateTime;

        private readonly string name;
        private KeyValuePair<int, int>[] dictDataIntToInt;
        private KeyValuePair<string, string>[] dictDataStringToString;
        private KeyValuePair<int, int>[] testDataIntToInt;
        private KeyValuePair<string, string>[] testDataStringToString;
        
        public TestFactoryHelper(
            string dictname,
            Factory_Delegate<int, int> factoryInt2Int,
            Factory_Delegate<string, string> factoryString2DateTime)
        {
            this.factoryForIntToInt = factoryInt2Int;
            this.factoryForStringToDateTime = factoryString2DateTime;
            this.name = dictname;
        }

        public IEnumerable<Test> GenerateTests()
        {
            this.dictDataStringToString = this.GenerateData_String2String(0, 15);
            this.testDataStringToString = this.GenerateData_String2String(500, 515);
            this.dictDataIntToInt = GenerateData_Int2Int(1, 500);
            this.testDataIntToInt = GenerateData_Int2Int(10500, 11000);

            List<Test> tests = new List<Test>();
            
            CommonTests<int, int> commonTestsIntToInt = new CommonTests<int, int>(
                this.factoryForIntToInt,
                this.dictDataIntToInt, 
                this.testDataIntToInt);
            tests.AddRange(commonTestsIntToInt.GenerateTests());

            CommonTests<string, string> commonTestsStringToDateTime = new CommonTests<string, string>(
                this.factoryForStringToDateTime,
                this.dictDataStringToString,
                this.testDataStringToString);
            tests.AddRange(commonTestsStringToDateTime.GenerateTests());

            return tests;
        }

        private static KeyValuePair<int, int>[] GenerateData_Int2Int(int lower, int upper)
        {
            KeyValuePair<int, int>[] result = new KeyValuePair<int, int>[upper - lower];
            for (int i = lower; i < upper; ++i)
            {
                result[i - lower] = new KeyValuePair<int, int>(i, upper + lower - i - 1);
            }

            return result;
        }

        private KeyValuePair<string, string>[] GenerateData_String2String(int lower, int upper)
        {
            KeyValuePair<string, string>[] result = new KeyValuePair<string, string>[upper - lower];

            for (int i = lower; i < upper; ++i)
            {
                string key = string.Format("Key {0}", i);
                string val = string.Format("Key {0}", upper - lower - 1 - i);

                result[i - lower] = new KeyValuePair<string, string>(key, val);
            }

            return result;
        }
    }
}
